package eu.robico.simulator.simulatorinterface.communication;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import eu.robico.simulator.simulatorinterface.SimulatorInterface;
import eu.robico.simulator.simulatorinterface.communication.Protocol.Trigger;
import eu.robico.simulator.simulatorinterface.communication.Protocol.Update;
import eu.robico.simulator.simulatorinterface.communication.Protocol.UpdateType;

public class Host 
{
	private Socket socket;
	
	private SimulatorInterface simulatorInterface;
	
	private HostListener listener;
	private HostWriter writer;
	
	private Status status = Status.CONNECTED;
	
	public enum Status
	{
		CONNECTED
	}
	
	public Host(SimulatorInterface simulatorInterface, String ip, short port) throws UnknownHostException, IOException
	{
		this.simulatorInterface = simulatorInterface;
		this.socket = new Socket(ip, port);
		//Create listener and writer
		BufferedReader input = new BufferedReader(new InputStreamReader(
				socket.getInputStream()));
		BufferedWriter output = new BufferedWriter(new OutputStreamWriter(
				socket.getOutputStream()));
		this.listener = new HostListener(this, input);
		this.listener.start();
		this.writer = new HostWriter(output);
		//At this point everything is ready for communication with this host
	}
	
	public void close()
	{
		try 
		{
			this.writer.sendDisconnect();
			this.writer.close();
		} 
		catch (IOException e) 
		{
			//this will regularly happen
			System.out.println("Conection already closed");
		}
		this.listener.close();
		this.simulatorInterface.disconnected();
	}
	
	void takeIntegerUpdate(Update<Integer> update)
	{
		simulatorInterface.takeIntegerUpdate(update);
	}
	
	void takeStringUpdate(Update<String> update)
	{
		simulatorInterface.takeStringUpdate(update);
	}
	
	public void sendTrigger(Trigger trigger)
	{
		try 
		{
			this.writer.sendTrigger(trigger);
		} 
		catch (IOException e) 
		{
			close();
			this.simulatorInterface.takeStringUpdate(new Update<String>(
					UpdateType.CONNECTIONERROR,
					"Disconnected"));
		}
	}
	
	public Status getStatus()
	{
		return status;
	}
}
